package com.keta.foundation.controller;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.keta.foundation.dao.UserRoleDAO;
import com.keta.foundation.entity.User;
import com.keta.foundation.service.UserService;
import com.keta.foundation.service.impl.UserServiceImpl;
import com.keta.foundation.shiro.IncorrectCaptchaException;
import com.keta.foundation.util.Exceptions;
import com.keta.foundation.util.dwz.AjaxObject;

/*
 * 登陆控制器
 * 处理登陆相关请求，以及shiro的回调地址处理
 */
@Controller
@RequestMapping("/login")
public class LoginController {

	private static final Logger logger = LoggerFactory.getLogger(LoginController.class);

	private static final String LOGIN_PAGE = "index/login";
	private static final String LOGIN_DIALOG = "index/login_dialog";

	/**
	 * 登录页面跳转
	 */
	@RequestMapping(method = RequestMethod.GET)
	public String login() {
		return LOGIN_PAGE;
	}

	/**
	 * 跳转到对话框登陆界面
	 */
	@RequestMapping(value = "/timeout")
	public String login_dialog() {
		return LOGIN_DIALOG;
	}

	/**
	 * 
	 * 接受POST方式的login请求，能执行到该方法说明Shiro登陆验证没有成功， 否则在Shiro Filter中就跳转到index了
	 */
	@RequestMapping(method = RequestMethod.POST)
	public String fail(String username, String password, HttpServletRequest request, HttpServletResponse response,
			Map<String, Object> map) throws IOException {

		String msg = parseException(request);

		map.put("msg", msg);
		map.put("username", username);

		return LOGIN_PAGE;
	}

	@RequestMapping(value = "/timeout/success")
	public @ResponseBody String loginDialog2AJAX() {
		return AjaxObject.newOk("登陆成功!").toString();
	}

	@RequestMapping(method = { RequestMethod.GET }, produces = {"text/plain;charset=UTF-8"}, headers = "X-Requested-With=XMLHttpRequest" )
	public @ResponseBody String loginDialog(ServletRequest request, ServletResponse respone) {
		respone.setCharacterEncoding("UTF-8");
		return AjaxObject.newTimeout("登陆超时,请重新登陆!").toString();
	}

	@RequestMapping(method = { RequestMethod.POST }, headers = "x-requested-with=XMLHttpRequest")
	public @ResponseBody String failDialog(ServletRequest request) {
		String msg = parseException(request);

		AjaxObject ajaxObject = new AjaxObject(msg);
		ajaxObject.setStatusCode(AjaxObject.STATUS_CODE_FAILURE);
		ajaxObject.setCallbackType("");

		return ajaxObject.toString();
	}

	/*
	 * 解析Shiro过滤器中抛出的异常
	 */
	private String parseException(ServletRequest request) {
		String errorString = (String) request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
		Class<?> error = null;
		try {
			if (errorString != null) {
				error = Class.forName(errorString);
			}
		} catch (ClassNotFoundException e) {
			logger.error(Exceptions.getStackTraceAsString(e));
		}

		String msg = "其他错误！";
		if (error != null) {
			if (error.equals(UnknownAccountException.class))
				msg = "未知帐号错误！";
			else if (error.equals(IncorrectCredentialsException.class))
				msg = "密码错误！";
			else if (error.equals(IncorrectCaptchaException.class))
				msg = "验证码错误！";
			else if (error.equals(AuthenticationException.class))
				msg = "认证失败！";
			else if (error.equals(DisabledAccountException.class))
				msg = "账号被冻结！";
		}

		return "登录失败，" + msg;
	}
}
